package mspbots.cw.business.core.orders;

import com.fasterxml.jackson.databind.JsonNode;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import mspbots.cw.business.core.BaseReceiver;
import mspbots.cw.common.ResultMsg;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.time.Duration;

/**
 * @author Jay.Yang
 */
@Log4j2
@Component
@RequiredArgsConstructor
public class OrdersReceiver extends BaseReceiver {

    private final OrdersRepository ordersRepository;

    @RabbitListener(queues = "connect-wise.orders.tl")
    public void process(ResultMsg resultMsg) {
        JsonNode entityNode = resultMsg.getEntity();
        Order data = super.objectMapper.convertValue(entityNode, Order.class);
        data.setId(null);
        data.setCwId(resultMsg.getId());
        data.setTenantCode(resultMsg.getTenantId());
        data.setSyncTime(resultMsg.getSyncDate());

        data.setStatusId(super.getLongValueId(entityNode.get("status")));
        data.setStatusName(super.getStringValueName(entityNode.get("status")));

        data.setCompanyId(super.getLongValueId(entityNode.get("company")));
        data.setCompanyName(super.getStringValueName(entityNode.get("company")));

        data.setBillingTermsId(super.getLongValueId(entityNode.get("billingTerms")));
        data.setBillingTermsName(super.getStringValueName(entityNode.get("billingTerms")));

        data.setBillToContactId(super.getLongValueId(entityNode.get("billToContact")));
        data.setBillToContactName(super.getStringValueName(entityNode.get("billToContact")));

        data.setContactId(super.getLongValueId(entityNode.get("contact")));
        data.setContactName(super.getStringValueName(entityNode.get("contact")));
        data.setUpdatedBy(super.getStringValue(entityNode.findValue("updatedBy")));
        data.setCreatedBy(super.getStringValue(entityNode.findValue("enteredBy")));
        data.setLastUpdatedTime(super.getDateTimeValue(entityNode.findValue("lastUpdated")));
        data.setTotal(super.getDoubleValue(entityNode.get("total")));
        data.setDueDate(super.getDateTimeValue(entityNode.get("dueDate")));
        data.setSalesRepId(super.getLongValueId(entityNode.get("salesRep")));
        data.setSalesRepName(super.getStringValueName(entityNode.get("salesRep")));
        data.setSalesRepIdentifier(super.getStringValue(ObjectUtils.isEmpty(entityNode.get("salesRep")) ? null : entityNode.get("salesRep").get("identifier")));
        this.ordersRepository.findByCwIdAndTenantCode(resultMsg.getId(), resultMsg.getTenantId())
                .map(result -> {
                    data.setId(result.getId());
                    return data;
                })
                .defaultIfEmpty(data)
                .flatMap(this.ordersRepository::save).block(Duration.ofSeconds(10));
    }

}
